home *** CD-ROM | disk | FTP | other *** search
- /* software tools format program -- C version -- Part 1
- * source: roff1.bds
- * version: November 27, 1981.
- */
-
- #define VERSION "November 27, 1981"
-
- #include tools.h
- #include roff.h
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- initst(argc, argv);
- main1();
- endst();
- }
-
- main1()
- {
- /* include: cpage, cparam, cout */
- char *arg;
- int i, fd, nf;
-
- finit();
-
- query("usage: ROFF [-s] [+n] [-n] [-pon] [files]\n");
-
- putlin("Welcome to roff version 0b:, ",SYS_TERM);
- putlin(VERSION, SYS_TERM);
- putlin("\n",SYS_TERM);
-
- /* open all files. examine options */
-
- nf = 0; /* number of open files */
-
- for (i = 1; (arg = getarg(i)) != EOS; i++) {
-
- /* -s option: stop after each page */
- if (arg [0] == '-' && tolower(arg[1]) == 's') {
- stopx = YES;
- }
-
- /* -po n option: page offset */
- else if ( arg [0] == '-' &&
- tolower(arg [1]) == 'p' &&
- tolower(arg [2]) == 'o'
- ) {
- set (&offset, atoi(arg + 3),
- arg [3], 0, 0, rmval - 1);
- }
-
- /* + n option: start printing with page n */
- else if (arg [0] == '+') {
- frstpg = atoi(arg + 1);
- }
-
- /* - n option: stop printing after page n */
- else if (arg [0] == '-' && arg[1] != EOS) {
- lastpg = atoi(arg + 2);
- }
-
- /* - or filename option: process input */
- else {
- if (arg [0] == '-') {
- fd = STDIN;
- }
- else {
- fd = open(arg, READ);
- }
- if (fd == ERR) {
- cant(arg);
- continue;
- }
- /* process one file */
- doroff(fd);
- nf++;
- if (fd != STDIN) {
- close(fd);
- }
- }
- } /* end of for loop */
-
- /* if no input files, do STDIN */
- if (nf == 0) {
- doroff(STDIN);
- }
-
- /* end gracefully */
- brk();
- if ( plval <= 100 &&
- (lineno > 0 || outp > 0)
- ) {
- /* flush last output */
- space(HUGE);
- }
-
- /* comment out ----- disable pagecontrol
- ifdef(PAGECONTROL,
- putc(PAGEJECT);
- putc(NEWLINE);
- )
- ----- end comment out */
- }
-
- /* bold - bold-face or overstrike a line */
-
- bold(buf, tbuf, size)
- char *buf, *tbuf; int size;
- {
- int i, j, k, k1;
-
- /* expand into tbuf */
- k = 0;
- j = 0;
- for (i = 0; ; i++) {
- if ( buf [i] != ' ' &&
- buf [i] != TAB &&
- buf [i] != BACKSPACE &&
- buf [i] != STARTU &&
- buf [i] != STOPU &&
- buf [i] != NEWLINE
- ) {
- k++;
- }
- else {
- /* over strike word */
- for (k1 = k; k1 > 0; k1--) {
- tbuf [j++] = buf [i - k1];
- }
- for (k1 = k; k1 > 0; k1--) {
- tbuf [j++] = BACKSPACE;
- }
- for (k1 = k; k1 > 0; k1--) {
- tbuf [j++] = buf [i - k1];
- }
-
- /* copy delimiter */
- tbuf [j++] = buf [i];
-
- /* reset counter */
- k = 0;
- if (buf [i] == NEWLINE) {
- break;
- }
- }
- }
- tbuf [j] = EOS;
- if (j >= size) {
- sys_error("bold");
- }
-
- /* copy tbuf back to buf */
- scopy(tbuf, 0, buf, 0);
- }
-
- /* brk - end current filled line */
-
- brk()
- {
- /* include cout */
-
- if (outp > 0) {
- outbuf [outp++] = NEWLINE;
- outbuf [outp] = EOS;
- put(outbuf);
- }
- outp = 0;
- outw = 0;
- outwds = 0;
- }
-
- /* center - center a line by setting tival */
-
- center(buf)
- char buf [];
- {
- /* include cparam */
-
- tival = max( (rmval + tival - width(buf)) / 2, 0);
- }
-
- /* command - perform formatting command */
-
- command(buf)
- char *buf;
- {
- /* include: cpage, cparam, cfiles, cnr */
-
- char name [MAXLINE], defn[MAXDEF];
-
- int val, argtyp; /* command line values */
- int spval; /* temp spacing param */
- int ismacro;
- int i, j;
-
- /* must look for macros before expanding escapes */
-
- i = 1;
- getwrd(buf, &i, name);
- ismacro = ludef(name, defn);
-
- doesc(buf, name, MAXLINE);
-
- /* get value of argument following command */
- i = 0;
- while ( buf [i] != ' ' &&
- buf [i] != TAB &&
- buf [i] != NEWLINE
- ) {
- i++;
- }
- /* warning: i used below as index into buf */
- val = getval(buf, &i, &argtyp);
-
- if (ismacro == YES) {
- /* evaluate args. push back definition */
- eval(buf, defn);
- return;
- }
-
- if (lu(buf,"fi")) {
- brk();
- fill = YES;
- }
- else if (lu(buf,"br")) {
- brk();
- }
- else if (lu(buf,"nf")) {
- brk();
- fill = NO;
- }
- else if (lu(buf,"ls")) {
- set(&lsval, val, argtyp, 1, 1, HUGE);
- }
- else if (lu(buf,"ce")) {
- brk();
- set(&ceval, val, argtyp, 1, 0, HUGE);
- }
- else if (lu(buf,"ul")) {
- cuval = 0;
- set(&ulval, val, argtyp, 0, 1, HUGE);
- }
- else if (lu(buf,"bd")) {
- set(&boval, val, argtyp, 0, 1, HUGE);
- }
- else if (lu(buf,"he")) {
- gettl(buf, ehead, ehlim);
- gettl(buf, ohead, ohlim);
- }
- else if (lu(buf,"fo")) {
- gettl(buf, efoot, eflim);
- gettl(buf, ofoot, oflim);
- }
- else if (lu(buf,"bp")) {
- /* perform break explicitly */
- brk();
- if (lineno > 0) {
- space(HUGE);
- }
- set(&curpag,val,argtyp,curpag+1,-HUGE,HUGE);
- newpag = curpag;
- }
- else if (lu(buf,"sp")) {
- set(&spval, val, argtyp, 1, 0, HUGE);
- space(spval);
- }
- else if (lu(buf,"in")) {
- brk();
- set(&inval, val, argtyp, 0, 0, rmval-1);
- tival = inval;
- }
- else if (lu(buf,"rm")) {
- set(&rmval, val, argtyp, PAGEWIDTH,
- tival + 1, HUGE);
- }
- else if (lu(buf,"ti")) {
- brk();
- set(&tival, val, argtyp, 0, 0, rmval);
- }
- else if (lu(buf,"pl")) {
- set(&plval, val, argtyp, PAGELEN,
- m1val+m2val+m3val+m4val+1, HUGE);
- bottom = plval - m3val - m4val;
- }
- else if (lu(buf,"po")) {
- set(&offset, val, argtyp, 0, 0, rmval-1);
- }
- else if (lu(buf,"m1")) {
- set(&m1val, val, argtyp, 3, 0,
- plval-m2val-m3val-m4val-1);
- }
- else if (lu(buf,"m2")) {
- set(&m2val, val, argtyp, 2, 0,
- plval-m1val-m3val-m4val-1);
- }
- else if (lu(buf,"m3")) {
- set(&m3val, val, argtyp, 2, 0,
- plval-m1val-m2val-m4val-1);
- bottom = plval - m3val - m4val;
- }
- else if (lu(buf,"m4")) {
- set(&m4val, val, argtyp, 3, 0,
- plval-m1val-m2val-m3val-1);
- bottom = plval - m3val - m4val;
- }
- else if (lu(buf,"eh")) {
- gettl(buf, ehead, ehlim);
- }
- else if (lu(buf,"oh")) {
- gettl(buf, ohead, ohlim);
- }
- else if (lu(buf,"ef")) {
- gettl(buf, efoot, eflim);
- }
- else if (lu(buf,"of")) {
- gettl(buf, ofoot, oflim);
- }
- else if (lu(buf,"cc")) {
- /* change command character */
- cchar = argtyp;
- if (cchar == EOS || cchar == NEWLINE) {
- cchar = '.';
- }
- }
- else if (lu(buf,"ne")) {
- if (lineno + val > bottom && lineno <= bottom){
- space(val);
- lineno = 0;
- }
- }
- else if (lu(buf,"bs")) {
- set(&bsval, val, argtyp, 1, 0, HUGE);
- }
- else if (lu(buf,"ju")) {
- rjust = YES;
- }
- else if (lu(buf,"nj")) {
- rjust = NO;
- }
- else if (lu(buf,"so")) {
- /* start new source file */
- if (getwrd(buf, &i, name) == 0) {
- return;
- }
- if (level + 1 >= MAXOFILES) {
- error("so commands nested too deeply.");
- }
- infile [level+1] = open(name, READ);
- if (infile [level+1] != ERR) {
- level++;
- }
- }
- else if (lu(buf,"cu")) {
- ulval = 0;
- set(&cuval, val, argtyp, 0, 1, HUGE);
- }
- else if (lu(buf,"de")) {
- dodef(buf, infile [level]);
- }
- else if (lu(buf,"nr")) {
- /* set number register */
- if (getwrd(buf, &i, name) == 0) {
- return;
- }
- fold(name);
- if (name [0] < 'a' || name[0] > 'z') {
- error("invalid number register name.");
- }
- val = getval(buf, &i, &argtyp);
- set(&nr [name[0]-'a'], val, argtyp,
- 0, -HUGE, HUGE);
- }
- else if (lu(buf,"st")) {
- /* space to line n from top of page */
- if (argtyp == '-') {
- spval = plval;
- }
- else {
- spval = 0;
- }
- set(&spval, val, argtyp, 0, 1, bottom);
- if (spval > lineno && lineno == 0) {
- phead();
- }
- if (spval > lineno) {
- space(spval - lineno);
- }
- }
- else {
- /* ignore unknown commands */
- return;
- }
- }
-
- /* return true if first two characters of buffer matches
- * the string.
- */
-
- BOOL lu (buf, string) char *buf, *string;
- {
- if ( buf [1] == string[0] &&
- buf [2] == string[1]
- ) {
- return(YES);
- }
- else {
- return(NO);
- }
- }
-
- /* dodef - define a command; .de xx is in buf
- * read lines until a .en is found
- */
-
- dodef(buf, fd)
- char *buf;
- int fd;
- {
- /* include cparam */
- char name [MAXNAME], defn [MAXDEF];
- int i;
-
- /* comment out -----
- printf("in dodef: buf = %s\n", buf);
- ----- end comment out */
-
- /* get name */
- i = 0;
- getwrd(buf, &i, name);
- i = getwrd(buf, &i, name);
-
- /* comment out -----
- printf("dodef: name = %s\n", name);
- ----- end comment out */
-
- if (i == 0) {
- /* null definition -- ignore */
- return;
- }
-
- /* allow arbitrary length names */
-
- i = 0;
- while (ngetln(buf, fd) != EOF) {
- /* .en terminates macro definition */
- if ( buf [0] == cchar &&
- buf [1] == 'e' &&
- buf [2] == 'n'
- ) {
- break;
- }
- addstr(buf, defn, &i, MAXDEF);
- }
-
- if (addset(EOS, defn, &i, MAXDEF) == NO) {
- error("definition too long.");
- }
- entdef(name, defn);
- }
-
- /* doesc - expand values of number regs into buf */
-
- doesc(buf, tbuf, size)
- char *buf, *tbuf; int size;
- {
- /* include cnr */
- int i, j;
-
- j = 0; /* expand into tbuf */
- for (i = 0; buf [i] != EOS && j < size; i++) {
- if (buf [i] != '@') {
- tbuf [j++] = buf[i];
- }
- else if (buf [i+1] == '@') {
- /* two at signs count as one */
- tbuf [j++] = '@';
- i++;
- }
- else if ( buf [i+1] == 'n' &&
- isalpha(buf [i+2])
- ) {
- /* @na is request for number reg a */
- j += itoc( nr [tolower(buf [i+2])-'a'],
- tbuf + j,
- size - j - 1
- );
- i += 2;
- }
- else {
- tbuf [j++] = buf[i];
- }
- }
- tbuf [j] = EOS;
- scopy(tbuf, 0, buf, 0);
- }
-
- /* doroff - format text in file fd */
-
- doroff(fd)
- int fd;
- {
- /* include cfiles, cparam */
- char inbuf [INSIZE];
-
- infile [0] = fd;
- for (level = 0; level >= 0; level--) {
- while (ngetln(inbuf, infile [level]) != EOF) {
-
- if (inbuf [0] == cchar) {
- command(inbuf);
- }
- else {
- text(inbuf);
- }
- }
-
- /* close an .so file */
- if (level > 0 && infile [level] != ERR) {
- close(infile [level]);
- }
- }
- }
-
- /* dotabs - expand tabs in buf */
-
- dotabs(buf, tbuf, size)
- char *buf, *tbuf; int size;
- {
- /* include cparam */
- int i, j;
-
- /* expand into tbuf */
- j = 0;
- for (i = 0; buf [i] != EOS && j < size; i++) {
- if (buf [i] == TAB) {
- while (j < size) {
- tbuf [j++] = ' ';
- if ( tabs [j] == YES ||
- j >= INSIZE
- ) {
- break;
- }
- }
- }
- else {
- tbuf [j++] = buf [i];
- }
- }
- tbuf [j] = EOS;
- scopy(tbuf, 0, buf, 0);
- }
-
- /* entdef - enter name and definition in macro table */
-
- entdef (name, defn)
- char *name, *defn;
- {
- /* include cmac */
- int i;
- char *locn;
-
- /* comment out -----
- printf("entdef: name = %s, defn = \n%s\n",name,defn);
- ----- end comment out */
-
- if ((locn = lookup (name, mactbl)) != 0) {
- /* erase old definition */
- delete(name, mactbl);
- }
- enter (name, defn, mactbl);
- }
-
- /* eval - evaluate defined command; push back definition.
- * buf contains a call to a macro.
- * defn contains its definition.
- * substitute args from buf into definition and
- * push it all back.
- */
-
- eval(buf, defn)
- char *buf, *defn;
- {
- int i, j, k;
- int argptr [10];
-
- /* comment out -----
- printf("eval: buf = %s\ndefn = %s\n", buf, defn);
- ----- end comment out */
-
- /* create null string */
- buf [0] = EOS;
-
- /* initialize pointers to null string */
- for (j = 0; j < 10; j++) {
- argptr [j] = 0;
- }
-
- /* up to 9 positional arguments are allowed.
- * $0 refers to command name.
- */
- for (i= 1, j = 0; j < 10; j++) {
-
- /* scan past blanks ending previous argument */
- skipbl(buf, &i);
- if (buf [i] == NEWLINE || buf[i] == EOS) {
- break;
- }
-
- /* point argptr at arg */
- argptr [j] = i;
- while ( buf [i] != ' ' &&
- buf [i] != TAB &&
- buf [i] != NEWLINE &&
- buf [i] != EOS
- ) {
- i++;
- }
- /* end argument */
- buf [i++] = EOS;
-
- /* comment out -----
- printf("argptr[%d] = %d,",j, argptr[j]);
- printf("buf + argptr[%d] = %s\n",
- j, buf + argptr[j]);
- ----- end comment out */
- }
-
- /* push the defintion back in reverse order.
- * substitute actual parameters for $1 ... $9
- * substitute command name for $0
- */
- for (k = length(defn) - 1; k > 0; k--) {
- if (defn [k-1] != ARGFLAG) {
- putbak(defn [k]);
- }
- else {
- if (defn [k] < '0' || defn [k] > '9') {
- putbak(defn [k]);
- }
- else {
- i = defn [k] - '0';
- pbstr(buf + argptr [i]);
- k--; /* skip over $ */
- }
- }
- }
- /* do last character */
- if (k >= 0) {
- putbak(defn [k]);
- }
- }
- }
-
- /* push the defintion back in reverse order.
- * substitute actual parameters for $1 ... $9
- * substitute command name